package com.qqtech.qquan.homemaking.service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.qqtech.core.common.enums.YesNoEnum;
import com.qqtech.core.common.exception.OrderException;
import com.qqtech.core.common.util.TimeUtil;
import com.qqtech.core.frame.dao.BaseDao;
import com.qqtech.core.frame.model.Result;
import com.qqtech.core.frame.service.BaseServiceImpl;
import com.qqtech.qquan.coupon.enums.CouponUserStatusDictEnum;
import com.qqtech.qquan.coupon.model.CouponBaseVo;
import com.qqtech.qquan.coupon.model.CouponUserVo;
import com.qqtech.qquan.coupon.service.CouponBaseService;
import com.qqtech.qquan.coupon.service.CouponUserService;
import com.qqtech.qquan.homemaking.dao.HomemakingBaseDao;
import com.qqtech.qquan.homemaking.dao.HomemakingItemDao;
import com.qqtech.qquan.homemaking.dao.HomemakingOrderDao;
import com.qqtech.qquan.homemaking.dao.HomemakingPubitemDao;
import com.qqtech.qquan.homemaking.dao.HomemakingTimeDao;
import com.qqtech.qquan.homemaking.dao.HomemakingTypeDao;
import com.qqtech.qquan.homemaking.enums.HomemakingBaseConst;
import com.qqtech.qquan.homemaking.enums.HomemakingOrderStatusDictEnum;
import com.qqtech.qquan.homemaking.enums.HomemakingTimeTypeDictEnum;
import com.qqtech.qquan.homemaking.model.HomemakingBaseVo;
import com.qqtech.qquan.homemaking.model.HomemakingItem;
import com.qqtech.qquan.homemaking.model.HomemakingItemQuery;
import com.qqtech.qquan.homemaking.model.HomemakingOrder;
import com.qqtech.qquan.homemaking.model.HomemakingOrderItemVo;
import com.qqtech.qquan.homemaking.model.HomemakingOrderQuery;
import com.qqtech.qquan.homemaking.model.HomemakingOrderVo;
import com.qqtech.qquan.homemaking.model.HomemakingTime;
import com.qqtech.qquan.homemaking.model.HomemakingType;
import com.qqtech.qquan.order.cache.OrderSysParamCache;
import com.qqtech.qquan.order.dao.OrderBaseDao;
import com.qqtech.qquan.order.enums.OrderBaseDeliveryStatusDictEnum;
import com.qqtech.qquan.order.enums.OrderBaseOrderStatusDictEnum;
import com.qqtech.qquan.order.enums.OrderBaseOrderTypeDictEnum;
import com.qqtech.qquan.order.enums.OrderBasePayStatusDictEnum;
import com.qqtech.qquan.order.enums.OrderBasePayTypeDictEnum;
import com.qqtech.qquan.order.enums.OrderBaseReturnStatusDictEnum;
import com.qqtech.qquan.order.enums.OrderBaseSubsidyTypeDictEnum;
import com.qqtech.qquan.order.enums.OrderConst;
import com.qqtech.qquan.order.enums.OrderCouponDictTypeEnum;
import com.qqtech.qquan.order.enums.OrderDeliverySendDeliveryTypeDictEnum;
import com.qqtech.qquan.order.enums.OrderDeliveryTypeDictEnum;
import com.qqtech.qquan.order.model.OrderBase;
import com.qqtech.qquan.order.model.OrderCoupon;
import com.qqtech.qquan.order.model.OrderDelivery;
import com.qqtech.qquan.order.model.OrderItem;
import com.qqtech.qquan.order.service.OrderCouponService;
import com.qqtech.qquan.order.service.OrderHandleService;
import com.qqtech.qquan.push.service.PushBizzService;
import com.qqtech.qquan.sms.service.SmsBizzService;
import com.qqtech.qquan.user.dao.UserAddressDao;
import com.qqtech.qquan.user.model.UserAddressVo;

@Service
public class HomemakingOrderServiceImpl extends BaseServiceImpl<HomemakingOrder>implements HomemakingOrderService {
	public static final Logger log = LoggerFactory.getLogger(HomemakingOrderServiceImpl.class);

	@Resource
	private HomemakingOrderDao homemakingOrderDao;

	@Resource
	private HomemakingBaseDao homemakingBaseDao;

	@Resource
	private HomemakingItemDao homemakingItemDao;

	@Resource
	private HomemakingTimeDao homemakingTimeDao;

	@Resource
	private OrderHandleService orderHandleService;

	@Resource
	private UserAddressDao userAddressDao;

	@Resource
	private HomemakingTimeService homemakingTimeService;

	@Resource
	private HomemakingPubitemDao homemakingPubitemDao;

	@Resource
	private HomemakingTypeDao homemakingTypeDao;
	@Resource
	private PushBizzService pushBizzService;
	@Resource
	private SmsBizzService smsBizzService;

	@Resource
	private OrderSysParamCache orderSysParamCache;
	@Resource
	private CouponBaseService couponBaseService;
	@Resource
	private CouponUserService couponUserService;
	@Resource
	private OrderCouponService orderCouponService;
	@Resource
	private OrderBaseDao orderBaseDao;
	
	@Override
	protected BaseDao<HomemakingOrder> getBaseDao() {
		return homemakingOrderDao;
	}

	public double getDistance(double lng1, double lat1, double lng2, double lat2) {
		double radLat1 = Math.toRadians(lat1);
		double radLat2 = Math.toRadians(lat2);
		double a = radLat1 - radLat2;
		double b = Math.toRadians(lng1) - Math.toRadians(lng2);
		double s = 2 * Math.asin(Math.sqrt(
				Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
		s = s * 6378137.0;// 取WGS84标准参考椭球中的地球长半径(单位:m)
		s = Math.round(s * 10000) / 10000;
		return s;
	}

	@Override
	public HomemakingOrderVo getByOrderNo(java.lang.String orderNo) {
		return homemakingOrderDao.getByOrderNo(orderNo);
	}

	@Override
	public Result handleSaveOrder(HomemakingOrderVo homemakingOrderVo) throws OrderException {
		Result result = new Result();
		HomemakingBaseVo homemakingBaseVo = homemakingBaseDao.getById(homemakingOrderVo.getBaseId());
		if (homemakingBaseVo == null) {
			result.addErr("服务不存在");
			return result;
		}
		// 从地址管理获取 homemakingOrderVo.getAddressId();
		UserAddressVo userAddress = userAddressDao.getById(homemakingOrderVo.getAddressId());
		if (userAddress != null) {
			if (userAddress.getCommunityId() == null) {
				result.addErr("地址信息不完整，请重新编辑您的地址");
			} else if (userAddress.getCommunityId().intValue() != homemakingBaseVo.getCommunityId().intValue()) {
				result.addErr("所选地址和服务不在同一个社区");
			}
		} else {
			result.addErr("地址不存在了");
		}
		if (homemakingBaseVo.getCreatorId().intValue() == homemakingOrderVo.getBuyerId()) {
			result.addErr("不能预约自己的服务");
		}
		if (!result.checkForm()) {
			return result;
		}
		Timestamp now = TimeUtil.now();
		OrderBase orderBase = new OrderBase();
		orderBase.setTotal(BigDecimal.ZERO);
		// orderBase.setOrderNo("");
		HomemakingType homemakingType = homemakingTypeDao.getById(homemakingBaseVo.getTypeId());
		orderBase.setTitle(homemakingType.getName());
		orderBase.setImg(homemakingType.getImg());
		orderBase.setOrderType(OrderBaseOrderTypeDictEnum.HOMEMAKING.getCode());
		orderBase.setBuyerId(homemakingOrderVo.getBuyerId());
		orderBase.setSellerId(homemakingBaseVo.getCreatorId());
		orderBase.setOrderStatus(OrderBaseOrderStatusDictEnum.UNCOMPLETED.getCode());
		orderBase.setOrderStatusAt(now);
		orderBase.setPayType(homemakingOrderVo.getPayType() == null ? OrderBasePayTypeDictEnum.ONLINE.getCode()
				: homemakingOrderVo.getPayType());
		orderBase.setPayStatus(OrderBasePayStatusDictEnum.UNPAYED.getCode());
		orderBase.setDeliveryStatus(OrderBaseDeliveryStatusDictEnum.UNSEND.getCode());
		orderBase.setDeliveryStatusAt(now);
		orderBase.setReturnStatus(OrderBaseReturnStatusDictEnum.NONEED.getCode());
		orderBase.setReturnStatusAt(now);
		orderBase.setIsCallBack(YesNoEnum.NO.getCode());
		orderBase.setAutoExpireAt(TimeUtil.addMins(now, 15)); // 未付款情况下自动失效时间//
		orderBase.setRemark(homemakingOrderVo.getBuyerRemark()); // 买家留言
		orderBase.setCommunityId(userAddress.getCommunityId());
		orderBase.setSubsidyType(OrderBaseSubsidyTypeDictEnum.NONE.getCode());
		orderBase.setSubsidy(BigDecimal.ZERO);
		List<OrderItem> orderItemList = new ArrayList<OrderItem>();
		for (HomemakingOrderItemVo hoItem : homemakingOrderVo.getHomemakingOrderItemVos()) {
			if (hoItem.getCount() != null && hoItem.getCount().intValue() > 0) {
				// HomemakingItem hItem =
				// homemakingItemDao.getById(hoItem.getHomemakingItemId());
				HomemakingItemQuery homemakingItemQuery = new HomemakingItemQuery();
				homemakingItemQuery.setBaseId(homemakingBaseVo.getId());
				homemakingItemQuery.setItemId(hoItem.getHomemakingPubitemId());
				HomemakingItem hItem = homemakingItemDao.getOne(homemakingItemQuery); // 自己发布的价格
				/*
				 * HomemakingPubitem hItem = homemakingPubitemDao.getById(hoItem
				 * .getHomemakingPubitemId()); 统一价格时候用到
				 */
				BigDecimal tempPriceTotal = hItem.getPrice().multiply(new BigDecimal(hoItem.getCount()));
				orderBase.setTotal(orderBase.getTotal().add(tempPriceTotal)); // 订单总额
				OrderItem orderItem = new OrderItem();
				// orderItem.setOrderNo("");
				orderItem.setProductId(hoItem.getHomemakingPubitemId());
				orderItem.setName(homemakingType.getName());
				orderItem.setPrice(hItem.getPrice());
				orderItem.setQuntity(hoItem.getCount());
				orderItem.setImg(homemakingType.getImg());
				orderItem.setProductSpecName(hoItem.getPubitemName());
				orderItemList.add(orderItem);
			}
		}
		orderBase.setOriginalTotal(orderBase.getTotal());
		if (homemakingOrderVo.getMinusPrice() == null) {
			homemakingOrderVo.setMinusPrice(BigDecimal.ZERO);
		}
		BigDecimal total=orderBase.getTotal().subtract(homemakingOrderVo.getMinusPrice());
		if(total.compareTo(BigDecimal.ZERO)==-1){
			orderBase.setTotal(BigDecimal.ZERO);
		}else{
			orderBase.setTotal(total);
		}
		OrderDelivery orderDelivery = new OrderDelivery();
		orderDelivery.setType(OrderDeliveryTypeDictEnum.SELLERSERVICE.getCode());
		orderDelivery.setDeliveryName("");
		orderDelivery.setDeliveryNo("");
		orderDelivery.setFreight(BigDecimal.ZERO);

		orderDelivery.setConsignee(userAddress.getContactName());
		orderDelivery.setPhone(userAddress.getContactPhone());
		orderDelivery.setAddress(userAddress.getAddress());
		// 免费的话，直接是已付款已发货
		if (orderBase.getTotal().compareTo(BigDecimal.ZERO) == 0) {
			orderBase.setPayStatus(OrderBasePayStatusDictEnum.PAYED.getCode());
		}
		result = orderHandleService.createOrder(orderBase, orderDelivery, orderItemList);
		if (result.checkForm()) {
			String orderNo = result.get("orderNo").toString();
			if(null!=homemakingOrderVo.getCouponUserId()){
				CouponUserVo couponUserVo=couponUserService.getById(homemakingOrderVo.getCouponUserId());
				if(couponUserVo.getStatus()==CouponUserStatusDictEnum.BE_USED.getCode()){
					throw new OrderException("优惠卷已被使用");
				}else{
					CouponBaseVo couponBaseVo=couponBaseService.getById(couponUserVo.getCouponId());
					OrderCoupon orderCoupon=new OrderCoupon();
					orderCoupon.setOrderNo(orderNo);
					orderCoupon.setRemark(couponBaseVo.getRemark());
					orderCoupon.setMinusPrice(couponBaseVo.getMinusPrice());
					orderCoupon.setType(OrderCouponDictTypeEnum.OTHER.getCode());
					orderCoupon.setUserId(couponUserVo.getUserId());
					int orderCouponId=orderCouponService.insert(orderCoupon);
					couponUserVo.setStatus(CouponUserStatusDictEnum.BE_USED.getCode());
					couponUserVo.setOrderCouponId(orderCouponId);
					couponUserService.updateById(couponUserVo);
				}
			}
			
			homemakingOrderVo.setOrderNo(orderNo);
			homemakingOrderVo.setStatus(HomemakingOrderStatusDictEnum.WAIT.getCode());
			homemakingOrderVo.setBuyerRemark(
					homemakingOrderVo.getBuyerRemark() == null ? "" : homemakingOrderVo.getBuyerRemark());
			homemakingOrderDao.insert(homemakingOrderVo);
			// 送水的 服务时间可以重复
			if (homemakingBaseVo.getTypeId().intValue() != HomemakingBaseConst.SONG_SHUI_ID) {
				if (homemakingOrderVo.getHomemakingTimeVos() != null && !homemakingOrderVo.getHomemakingTimeVos().isEmpty()) {
					for (HomemakingTime t : homemakingOrderVo.getHomemakingTimeVos()) {
						t.setBaseId(homemakingOrderVo.getBaseId());
						t.setType(HomemakingTimeTypeDictEnum.ORDERED.getCode());
						t.setOrderNo(homemakingOrderVo.getOrderNo());
						try {
							homemakingTimeDao.insert(t);
						} catch (Exception e) {
							result.addErr("已经有人预定了" + t.getServiceDateStr() + " " + t.getServiceHourStr());
							throw new OrderException("已经有人预定了" + t.getServiceDateStr() + " " + t.getServiceHourStr());
						}
					}
				}
			}
			pushBizzService.orderSelected(orderNo);
			if ((homemakingOrderVo.getPayType() != null && OrderBasePayTypeDictEnum.ONDELIVERY.getCode() == homemakingOrderVo.getPayType()) 
					|| (result.getMap().containsKey("payStatus") && Integer.valueOf(result.get("payStatus").toString())==OrderBasePayStatusDictEnum.PAYED.getCode())) {
				smsBizzService.orderPayedOrOndelivery(orderNo);
			}
		}
		return result;
	}

	/**
	 * 更新状态为“已服务”,等于卖家发货
	 */
	@Override
	public Result handleCompleteService(String orderNo) throws OrderException {
		Result r = new Result();
		HomemakingOrder homemakingOrder = homemakingOrderDao.getByOrderNo(orderNo);
		if (homemakingOrder != null) {
			if (homemakingOrder.getStatus() == HomemakingOrderStatusDictEnum.WAIT.getCode()) {
				HomemakingOrder update = new HomemakingOrder();
				update.setId(homemakingOrder.getId());
				update.setStatus(HomemakingOrderStatusDictEnum.FINISH.getCode());
				update.setDoneAt(TimeUtil.now());
				update.setUpdAt(update.getDoneAt());
				homemakingOrderDao.updateById(update);
				OrderDelivery orderDelivery = new OrderDelivery();
				orderDelivery.setOrderNo(orderNo);
				r = orderHandleService.sended(orderNo, 2, OrderDeliverySendDeliveryTypeDictEnum.SELLER.getCode(), null, null); // 不需要物流
				if (!r.checkForm()) {
					throw new OrderException(r.getMsg());
				}
			} else {
				r.addErr("该预约已服务");
			}
		} else {
			r.addErr("参数无效");
		}
		return r;
	}

	@Override
	public Result handleCancelOrder(String orderNo) {
		Result r = new Result();
		HomemakingOrder homemakingOrder = homemakingOrderDao.getByOrderNo(orderNo);
		if (homemakingOrder != null) {
			if (homemakingOrder.getServiceAt() != null) {
				if (homemakingOrder.getStatus().intValue() == HomemakingOrderStatusDictEnum.WAIT.getCode()) {
					OrderBase orderBase = orderBaseDao.getByOrderNo(orderNo);
					if (orderBase.getPayType() == OrderBasePayTypeDictEnum.ONLINE.getCode() 
							&& orderBase.getPayStatus().intValue() == OrderBasePayStatusDictEnum.PAYED.getCode()) {
						int minsBetween = TimeUtil.minsOfTwo(TimeUtil.now(), homemakingOrder.getServiceAt());
						String sysValue = orderSysParamCache.get(OrderConst.DICTYPE_ORDER_ONLINE_NOCANCEL_BEFORE_HOURS, "1");
						if (minsBetween > Integer.valueOf(sysValue) * 60) { //X个小时外取消订单全额退款
							r.put("returnPercent", 1.0);
						} else if (minsBetween < Integer.valueOf(sysValue) * 60 && minsBetween > 0) { //X个小时内取消订单退款50%，
							r.put("returnPercent", 0.5);
						} else if (minsBetween > -180) {
							r.addErr("若服务人员没有来，可在服务时间后3小时取消");
							return r;
						} else {
							r.put("returnPercent", 1.0);
						}
					}
					HomemakingOrder update = new HomemakingOrder();
					update.setId(homemakingOrder.getId());
					update.setStatus(HomemakingOrderStatusDictEnum.CANCEL.getCode());
					update.setUpdAt(TimeUtil.now());
					homemakingOrderDao.updateById(update);
					// 去掉订单所选时间
					homemakingTimeService.deleteByOrderNo(orderNo);
					/*if (minsBetween < Integer.valueOf(sysValue) * 60 && minsBetween > -180) {
						r.addErr("服务开始前" + sysValue + "小时不能取消\r\n若服务人员没有来服务，可在服务时间后3小时取消");
					} else {
						HomemakingOrder update = new HomemakingOrder();
						update.setId(homemakingOrder.getId());
						update.setStatus(HomemakingOrderStatusDictEnum.CANCEL.getCode());
						update.setUpdAt(update.getDoneAt());
						homemakingOrderDao.updateById(update);
						// 去掉订单所选时间
						homemakingTimeService.deleteByOrderNo(orderNo);
					}*/
				} else if (homemakingOrder.getStatus().intValue() == HomemakingOrderStatusDictEnum.FINISH.getCode()) {
					r.addErr("已服务，不能取消");
				} else {
					r.addErr("已取消");
				}
			} else {
				r.addErr("没有服务时间");
			}
		} else {
			r.addErr("没有这个订单");
		}
		return r;
	}

	/**
	 * 确认服务完成，订单完成,家政服务的预约数量加1
	 * 
	 * @param orderNo
	 * @return
	 * @throws OrderException
	 */
	@Override
	public Result handleConfirmService(String orderNo) {
		Result r = new Result();
		HomemakingOrder homemakingOrder = homemakingOrderDao.getByOrderNo(orderNo);
		if (homemakingOrder != null) {
			if (homemakingOrder.getStatus() == HomemakingOrderStatusDictEnum.FINISH.getCode()) {
				homemakingBaseDao.addOrderedCount(homemakingOrder.getBaseId());
			} else {
				r.addErr("未完成服务");
			}
		} else {
			r.addErr("没有该订单");
		}
		return r;
	}

	@Override
	public int getServiceCount(Integer creatorId, Timestamp doneAtBegin, Timestamp doneAtEnd) {
		if (creatorId == null) {
			return 0;
		}
		HomemakingOrderQuery q = new HomemakingOrderQuery();
		q.setCreatorId(creatorId);
		q.setDoneAtBegin(doneAtBegin);
		q.setDoneAtEnd(doneAtEnd);
		return homemakingOrderDao.queryCountByDoneAt(q);
	}

	@Override
	public Page<HomemakingOrderVo> queryPageListBySeller(HomemakingOrder query, Pageable pageable) {
		return homemakingOrderDao.queryPageListBySeller(query, pageable);
	}

	@Override
	public Result handleCancelOrderBySeller(String orderNo) {
		Result r = new Result();
		HomemakingOrder homemakingOrder = homemakingOrderDao.getByOrderNo(orderNo);
		if (homemakingOrder != null) {
			HomemakingOrder update = new HomemakingOrder();
			update.setId(homemakingOrder.getId());
			update.setStatus(HomemakingOrderStatusDictEnum.CANCEL.getCode());
			update.setUpdAt(TimeUtil.now());
			homemakingOrderDao.updateById(update);
			// 去掉订单所选时间
			homemakingTimeService.deleteByOrderNo(orderNo);
		} else {
			r.addErr("没有这个订单");
		}
		return r;
	}
}